/**
 * @author Shen Yi - bm2736892@gmail.com
 */

var PostProcessing = {
	
	compoundType : {
		"MUL" : 1,
		"ADD" : 2
	},
	
	opCount : 1,
	
	/**
	 * 
	 * @param {o3d.Texture} inputTexture
	 * @param {int} power
	 * @param {!Boolean} output
	 */
	gauss : function(inputTexture, power, output){
		var sampler = TextureManager.createSampler("PP_sampler_gauss_" + this.opCount, {"minFilter" : "ANISOTROPIC", "maxAnisotropy" : 4});
		sampler.texture = inputTexture;
		this.opCount++;
		return this.basic("gauss_" + this.opCount, {"tex1" : sampler, "power" : power}, "media/shaders/PostProcessing/gauss.shader", output);
	},
	/**
	 * @todo: improve it
	 * @param {o3d.Texture} inputTexture
	 * @param {int} power
	 * @param {!Boolean} output
	 */
	gaussEdge : function(inputTexture, power, output){
		var sampler = TextureManager.createSampler("PP_sampler_gauss_edge_" + this.opCount, {"minFilter" : "ANISOTROPIC", "maxAnisotropy" : 4});
		sampler.texture = inputTexture;
		this.opCount++;
		return this.basic("gauss_edge_" + this.opCount, {"tex1" : sampler, "positionTex" : DeferredShading.getGBuffer().getPositionSampler(), "power" : power}, "media/shaders/PostProcessing/gaussEdge.shader", output);
	},
	/**
	 * 
	 * @param {o3d.Texture} inputTexture1
	 * @param {o3d.Texture} inputTexture2
	 * @param compoundType
	 * @param {!Boolean} output
	 */
	compound : function(inputTexture1, inputTexture2, compoundType, output){
		var option = {"minFilter" : "ANISOTROPIC", "maxAnisotropy" : 4};
		var sampler1 = TextureManager.createSampler("PP_sampler_compound_2_"+this.opCount, option);
		sampler1.texture = inputTexture1;
		
		var sampler2 = TextureManager.createSampler("PP_sampler_compound_1_"+this.opCount, option);
		sampler2.texture = inputTexture2;
		
		compoundType = isset(compoundType) ? compoundType : this.compoundType.MUL
		this.opCount++;
		return this.basic("compound_"+this.opCount, {
			"tex1" : sampler1,
			"tex2" : sampler2,
			"compoundType" : compoundType,
		}, "media/shaders/PostProcessing/compound.shader", output)
	},
	
	/**
	 * 
	 * @param {Texture} inputTexture
	 * @param {Float} threshold
	 * @param {!Boolean} output
	 */
	extract : function(inputTexture, threshold, output){
		var sampler = TextureManager.createSampler("PP_sampler_extract", {"minFilter" : "ANISOTROPIC", "maxAnisotropy" : 4});
		sampler.texture = inputTexture;
		return this.basic("extract", {"tex1" : sampler, "threshold" : threshold}, "media/shaders/PostProcessing/extract.shader", output);
	},
	/**
	 * 
	 * @param {Texture} inputTexture
	 * @param {!Boolean} output
	 */
	gray : function(inputTexture, output){
		var sampler = TextureManager.createSampler("PP_sampler_gray", {"minFilter" : "ANISOTROPIC", "maxAnisotropy" : 4});
		sampler.texture = inputTexture;
		return this.basic("gray", {"tex1" : sampler}, "media/shaders/PostProcessing/gray.shader", output);
	},
	/**
	 * 
	 * @param {String} name
	 * @param {Object} param
	 * @param {String} shaderPath
	 * @param {!Boolean} output
	 */
	basic : function(name, param, shaderPath, output){
		var renderTarget = TextureManager.createRenderTarget2D("PP_rendertarget_"+name, 512*DeferredShading.size, 512*DeferredShading.size, "XRGB8");
		
		if(isset(output) && output){
			var camera = SceneManager.createCamera("PP_camera_"+name, 41);
		}else{
			var camera = SceneManager.createCamera("PP_camera_"+name, 41, renderTarget.name);
		}
		
		camera.setOrthographic();
		var material = MaterialManager.createMaterialFromShader("PP_material_"+name, shaderPath);
		
		for(var paramName in param){
			material.getParam(paramName).value = param[paramName];
		}
		
		MaterialManager.bindCamera(material.name, camera.name);
		
		var plane = SceneManager.createPlane("PP_plane_"+name, material.name, 2, 2, 2, 2);
		plane.rotateX(Math.PI / 2);
		SceneManager.addTransformTo(plane.name, camera.name);
		//update final render target;
		return renderTarget;
	}
}
